# @Time : 2021/6/19 21:53
# @Author : Li Kunlun
# @Description : 批训练
import torch
import torch.utils.data as Data  # 添加模块

torch.manual_seed(1)  # reproducible

BATCH_SIZE = 5  # 批训练的数据个数
# BATCH_SIZE = 8

x = torch.linspace(1, 10, 10)  # this is x data (torch tensor)
y = torch.linspace(10, 1, 10)  # this is y data (torch tensor)

"""
先转换成 torch 能识别的 Dataset（将训练数据的特征和标签组合）,torch_dataset包含的数据如下：
    tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
    tensor([10.,  9.,  8.,  7.,  6.,  5.,  4.,  3.,  2.,  1.])
"""
torch_dataset = Data.TensorDataset(x, y)
# 把 dataset 放入 DataLoader
# 数据加载器，组合数据集和采样器，并在数据集上提供单进程或多进程迭代器。它可以对数据集Dataset作进一步的设置。
loader = Data.DataLoader(
    dataset=torch_dataset,  # torch TensorDataset format
    batch_size=BATCH_SIZE,  # mini batch size
    shuffle=True,  # random shuffle for training
    num_workers=2,  # subprocesses for loading data（多线程来读数据）
)


def show_batch():
    for epoch in range(3):  # train entire dataset 3 times（# 训练所有的数据 3 次）
        #  每一步 loader 释放一小批数据用来学习
        for step, (batch_x, batch_y) in enumerate(loader):  # for each training step
            # train your data...（假设这里就是你训练的地方...）
            """
            1、shuffle=True时数据输出情况：
                Epoch:  0 | Step:  0 | batch x:  [5. 3. 1. 7. 9.] | batch y:  [ 6.  8. 10.  4.  2.]
                Epoch:  0 | Step:  1 | batch x:  [ 8. 10.  2.  6.  4.] | batch y:  [3. 1. 9. 5. 7.]
                Epoch:  1 | Step:  0 | batch x:  [5. 9. 2. 6. 1.] | batch y:  [ 6.  2.  9.  5. 10.]
                Epoch:  1 | Step:  1 | batch x:  [ 3.  4.  7. 10.  8.] | batch y:  [8. 7. 4. 1. 3.]
                Epoch:  2 | Step:  0 | batch x:  [6. 9. 4. 8. 7.] | batch y:  [5. 2. 7. 3. 4.]
                Epoch:  2 | Step:  1 | batch x:  [10.  3.  2.  1.  5.] | batch y:  [ 1.  8.  9. 10.  6.]
            2、shuffle=False时数据输出情况：
                Epoch:  0 | Step:  0 | batch x:  [1. 2. 3. 4. 5.] | batch y:  [10.  9.  8.  7.  6.]
                Epoch:  0 | Step:  1 | batch x:  [ 6.  7.  8.  9. 10.] | batch y:  [5. 4. 3. 2. 1.]
                Epoch:  1 | Step:  0 | batch x:  [1. 2. 3. 4. 5.] | batch y:  [10.  9.  8.  7.  6.]
                Epoch:  1 | Step:  1 | batch x:  [ 6.  7.  8.  9. 10.] | batch y:  [5. 4. 3. 2. 1.]
                Epoch:  2 | Step:  0 | batch x:  [1. 2. 3. 4. 5.] | batch y:  [10.  9.  8.  7.  6.]
                Epoch:  2 | Step:  1 | batch x:  [ 6.  7.  8.  9. 10.] | batch y:  [5. 4. 3. 2. 1.]
            3、每步都导出了5个数据进行学习. 然后每个 epoch 的导出数据都是先打乱了以后再导出。
                假如改变一下 BATCH_SIZE = 8,  step=0 会导出8个数据, 在 step=1 就只给你返回这个 epoch 中剩下的数据。
            """
            # 打印出来一些数据
            print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',
                  batch_x.numpy(), '| batch y: ', batch_y.numpy())


if __name__ == '__main__':
    show_batch()
